package com.ziyueyuwen.xiniao.util;

import com.suyeer.basic.util.ExecutorUtil;
import com.suyeer.basic.util.LogUtil;
import com.ziyueyuwen.xiniao.enums.OssPathEnum;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.concurrent.ExecutorService;

import static com.ziyueyuwen.xiniao.util.ConstUtil.VIDEO_FILE_PATH;

/**
 * @author jun 2018/12/8.
 */
public class AudioUtil {
    /**
     * ffmpeg 程序所在的路径
     */
    private final static String SHELL_WAV_TO_MP3 = "ffmpeg -i %s -f mp3 -acodec libmp3lame -y %s";
    private final static String SHELL_COMPRESS_MP4_FILE = "ffmpeg -y -i %s -r 25 -vcodec libx264 -b 512K %s";
    private final static String SHELL_SPX_TO_WAV = "speex2wav %s %s";
    private final static String DELETE_AUDIO_FILE = "rm -f /data/audio/";
    private final static ExecutorService EXECUTOR_SERVICE = ExecutorUtil.newFixedThreadPool(10, "handle_android_mp4_file");

    public static void handleAndroidMp4File(String ossFileName, MultipartFile file, OssPathEnum ossPath) {
        EXECUTOR_SERVICE.execute(() -> {
            try {
                String localFileName = OssUtil.getUniqueFileName(ossFileName);
                String localFilePath = VIDEO_FILE_PATH + localFileName;
                String ossFilePath = VIDEO_FILE_PATH + ossFileName;
                File localFile = new File(localFilePath);
                FileUtils.copyToFile(file.getInputStream(), localFile);
                compressMp4File(localFilePath, ossFilePath);
                File ossFile = new File(ossFilePath);
                OssUtil.putObjectToOss(ossFile, ossPath);
            } catch (Exception e) {
                LogUtil.error(e);
            }
        });
    }

    private static void compressMp4File(String originalFilePath, String newFilePath) throws Exception {
        try {
            execShell(String.format(SHELL_COMPRESS_MP4_FILE, originalFilePath, newFilePath), "压缩MP4");
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error(e);
            throw new Exception(e.getMessage());
        }
    }

    public static void spx2wav(String spxFilePath, String wavFilePath) throws Exception {
        try {
            execShell(String.format(SHELL_SPX_TO_WAV, spxFilePath, wavFilePath), "speex 转 mp3");
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error(e);
            throw new Exception(e.getMessage());
        }
    }

    public static void wav2mp3(String wavFilePath, String mp3FilePath) throws Exception {
        try {
            execShell(String.format(SHELL_WAV_TO_MP3, wavFilePath, mp3FilePath), "wav 转 mp3");
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.error(e);
            throw new Exception(e.getMessage());
        }
    }

    public static void deleteFile(String fileName) {
        try {
            execShell(DELETE_AUDIO_FILE + fileName, "删除文件");
        } catch (Exception e) {
            LogUtil.error(e);
        }
    }

    private static void execShell(String shellStr, String shellDes) throws Exception {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec(shellStr);
        InputStream in = process.getErrorStream();
        String result = IOUtils.toString(in, Charset.defaultCharset());
        LogUtil.info(result);
        if (process.exitValue() != 0) {
            throw new RuntimeException(String.format("Shell执行失败, 命令描述: %s, 脚本: %s", shellDes, shellStr));
        }
    }
}